package com.blen.videolib.edit;

import android.graphics.Bitmap;
import android.graphics.Matrix;
import android.media.MediaMetadataRetriever;
import android.os.Handler;
import android.os.Message;

import com.blen.videolib.VideoSDK;
import com.blen.videolib.util.FFUtils;
import com.blen.videolib.util.StringUtils;
import icangyu.base.utils.LogUtils;

import java.io.File;
import java.util.concurrent.ThreadPoolExecutor;

/**
 * ================================================
 * 作    者：顾修忠-guxiuzhong@youku.com/gfj19900401@163.com
 * 版    本：
 * 创建日期：2017/3/2-下午7:06
 * 描    述：
 * 修订历史：
 * ================================================
 */

public class VideoExtractFrameAsyncUtils {

    private Handler mHandler;
    private  int extractW;
    private  int extractH;
    private ThreadPoolExecutor executor = VideoSDK.mExecutor;

    public VideoExtractFrameAsyncUtils(int extractW, int extractH, Handler mHandler) {
        this.mHandler = mHandler;
        this.extractW=extractW;
        this.extractH=extractH;
    }

    public void getVideoThumbnailsInfoForEdit(String videoPath, String OutPutFileDirPath, long startPosition, long endPosition, int thumbnailsCount) {
        File f = new File(OutPutFileDirPath);
        if(!f.exists()){
            f.mkdir();
        }
        MediaMetadataRetriever metadataRetriever = new MediaMetadataRetriever();
        metadataRetriever.setDataSource(videoPath);
        int interval =(int)( (endPosition - startPosition) / (thumbnailsCount));
        float r = 1000f*(thumbnailsCount)/(endPosition-startPosition);
//        genAllPic(videoPath,r,thumbnailsCount,OutPutFileDirPath);
//        for (int i = 0; i < thumbnailsCount; i++) {
//            if (stop) {
//                LogUtils.d("ExtractFrame", "-------ok-stop-stop-->>>>>>>>>");
//                metadataRetriever.release();
//                break;
//            }
//            long time = startPosition + interval * i;
//            long t = i==thumbnailsCount-1?endPosition-(interval>1000?800:50):time;
            //TODO 多线程优化创建的MediaMetadataRetriver对象
//            if(executor!=null) {
//                executor.execute(() -> {
//                    sendAPic(extractFrame(videoPath, t, OutPutFileDirPath), t);
//                });
//            }else {
//                sendAPic(extractFrame(videoPath, t, OutPutFileDirPath), t);
//            sendAPic(extractFrameFFmpeg(videoPath, t, OutPutFileDirPath), t);
//            }
//        }
        int roll = thumbnailsCount/5;
        for(int i=0;i<roll;i++){
            genAllPic(videoPath,i,interval,r,5,OutPutFileDirPath);
        }
        if(thumbnailsCount%5!=0){
            genAllPic(videoPath,roll,interval,r,thumbnailsCount%5,OutPutFileDirPath);
        }
        metadataRetriever.release();
    }

    private void genAllPic(String videoPath,int i, int interval,float r,int cnt, String outPath) {
        if(stop) return;
        String[] cmd = {
                "ffmpeg",
                "-ss",
                String.valueOf(((i*5)*interval)/1000),
//                "-t",
//                String.valueOf(((i+1)*cnt-1)*r),
                "-i",
                videoPath,
                "-r",
                ""+r,
                "-y",
//                "-f",
//                "-image2",
                "-vframes",
                ""+cnt,
                "-s",
                extractW+"x"+extractH,
                outPath+"img"+i+"-%1d.jpeg"
        };
//        LogUtils.b("ffmpeg cmd is:" + StringUtils.concat(cmd," "));
        long start = System.currentTimeMillis();
        int code = FFUtils.run(cmd);
        LogUtils.b("ffmpeg code is "+code);
        if(code == 0){
//            LogUtils.d("cutTime","time is:"+(System.currentTimeMillis()-start));
            if(stop) return;
            for(int j=1;j<=cnt;j++){
                sendAPic(outPath+"img"+i+"-"+j+".jpeg",i*5+j);
            }
        }
        LogUtils.d("cutTime","time is:"+(System.currentTimeMillis()-start));
    }

    /**
     * 成功一张add一张
     *
     * @param path path
     * @param time time
     */
    private void sendAPic(String path, long time) {
        if(stop) return;
        VideoCutTimeInfo info = new VideoCutTimeInfo();
        info.path = path;
        info.time = time;
        Message msg = mHandler.obtainMessage(ExtractFrameWorkThread.MSG_SAVE_SUCCESS);
//        Message msg = new Message();
        msg.obj = info;
        mHandler.sendMessage(msg);
    }

    private String extractFrame(String videoPath, long time, String OutPutFileDirPath) {
        if(stop) return null;
        MediaMetadataRetriever metadataRetriever = new MediaMetadataRetriever();
        metadataRetriever.setDataSource(videoPath);
        Bitmap bitmap = metadataRetriever.getFrameAtTime(time * 1000, MediaMetadataRetriever.OPTION_CLOSEST_SYNC);
        if (bitmap != null) {
            Bitmap bitmapNew= scaleImage(bitmap);
            String path= PictureUtils.saveImageToSDForEdit(bitmapNew, OutPutFileDirPath, System.currentTimeMillis() + "_" + time + PictureUtils.POSTFIX);
            if (bitmapNew!=null &&!bitmapNew.isRecycled()) {
                bitmapNew.recycle();
                bitmapNew = null;
            }
            metadataRetriever.release();
            return path;
        }
        metadataRetriever.release();
        return null;
    }

    private String extractFrameFFmpeg(String videoPath, long time, String OutPutFileDirPath) {
        String outPath = new StringBuilder()
                .append(OutPutFileDirPath)./*append("/").*/append(System.currentTimeMillis()).append("_").append(time).append(PictureUtils.POSTFIX).toString();
        StringBuilder builder = new StringBuilder();
        // ffmpeg -ss 1000.4 -i input.mp4 -y  -vframes 1 output.jpg
        // -y 如果存在就替换
//        builder.append("ffmpeg -ss ").append(time/1000f)
////                .append("-t 0.01")
//                .append(" -i ").append(videoPath)
//                .append(" -y -vframes 1 ")
////                .append(" -f image2 ")
//                .append(" -s ").append(extractW).append("x").append(extractH)
//                .append(" ")
//                .append(outPath)
//                ;
        //是否存在?
        String[] cmd = {
                "ffmpeg",
                "-ss",
                ""+time/1000f,
                "-i",
                videoPath,
                "-y",
                "-vframes",
                "1",
                "-s",
                extractW+"x"+extractH,
                outPath
        };
        LogUtils.b("cmd is :"+cmd.toString());
        long start = System.currentTimeMillis();
        if(FFUtils.run(cmd) == 0){
            LogUtils.d("blensmile",outPath);
            LogUtils.d("cutTime","time is:"+(System.currentTimeMillis()-start));
            LogUtils.d("blensmile1", StringUtils.concat(cmd));
            return outPath;
        }
        LogUtils.d("cutTime","time is:"+(System.currentTimeMillis()-start));
        return null;
    }

    /**
     * 设置固定的宽度，高度随之变化，使图片不会变形
     *
     * @param bm Bitmap
     * @return Bitmap
     */
    private Bitmap scaleImage(Bitmap bm) {
        if (bm == null) {
            return null;
        }
        int width = bm.getWidth();
        int height = bm.getHeight();
        float scaleWidth = extractW * 1.0f / width;
//        float scaleHeight =extractH*1.0f / height;
        Matrix matrix = new Matrix();
        matrix.postScale(scaleWidth, scaleWidth);
        Bitmap newBm = Bitmap.createBitmap(bm, 0, 0, width, height, matrix,
                true);
        if (!bm.isRecycled()) {
            bm.recycle();
            bm = null;
        }
        return newBm;
    }


    private volatile boolean stop;

    public void stopExtract() {
        stop = true;
    }
}
